Skip to content

Conversation

YangKeao
Copy link
Member

@YangKeao YangKeao commented Jun 20, 2024

What problem does this PR solve?

Issue Number: close #54029, close #54044

Problem Summary:

For some json functions, the arg verification is not implemented correctly:

  1. For json_type, it didn't verify the type of args.
  2. For many other json functions, they didn't verify the charset of the args.

For PREPARE, the param marker is set to binary string type, which is not expected. This PR will give it a default collation. It will not affect the EXECUTE, because when it's executing a statement, it'll infer the collation according to the datum (whose collation is set according to the collation settings of the connection).

What changed and how does it work?

  1. Add a unified function to verify the args of json functions.
  2. Modify the collation of param marker from binary to default collation.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Release note

Fix the issue that `json_type` can accept non-JSON arguments.
Fix the issue that some json functions accept binary string arguments.
Fix the issue that `PREPARE` will fail if the statement contains some json related functions.

@ti-chi-bot ti-chi-bot bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 20, 2024
Copy link

codecov bot commented Jun 20, 2024

Codecov Report

Attention: Patch coverage is 94.23077% with 3 lines in your changes missing coverage. Please review.

Project coverage is 73.3582%. Comparing base (35d5739) to head (9d0d069).
Report is 21 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #54145        +/-   ##
================================================
+ Coverage   72.8582%   73.3582%   +0.4999%     
================================================
  Files          1672       1676         +4     
  Lines        462955     468918      +5963     
================================================
+ Hits         337301     343990      +6689     
+ Misses       104875     104169       -706     
+ Partials      20779      20759        -20     
Flag Coverage Δ
integration 43.3946% <94.2307%> (?)
unit 72.3408% <80.7692%> (+0.0950%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 52.7673% <ø> (ø)
parser ∅ <ø> (∅)
br 43.5939% <ø> (-1.4938%) ⬇️
---- 🚨 Try these New Features:

@YangKeao
Copy link
Member Author

/hold

Also consider #54044 (comment). Maybe it's not good to verify args type/charset in getFunction, because it'll be called in PREPARE stage.

@ti-chi-bot ti-chi-bot bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 20, 2024
Copy link

ti-chi-bot bot commented Jul 5, 2024

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@ti-chi-bot ti-chi-bot bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 5, 2024
@dveeden
Copy link
Contributor

dveeden commented Nov 18, 2024

@YangKeao can you update this PR?

@YangKeao YangKeao force-pushed the fix-54029 branch 2 times, most recently from 8371d26 to 51db52c Compare November 19, 2024 11:26
@YangKeao
Copy link
Member Author

@YangKeao can you update this PR?

Done. PTAL

@YangKeao
Copy link
Member Author

/retest

@YangKeao YangKeao requested a review from dveeden November 20, 2024 05:44
@YangKeao
Copy link
Member Author

/unhold

@ti-chi-bot ti-chi-bot bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 20, 2024
@YangKeao YangKeao removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 20, 2024
@YangKeao YangKeao added the needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. label Nov 20, 2024
Copy link
Contributor

@windtalker windtalker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ti-chi-bot ti-chi-bot bot added approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Nov 20, 2024
@YangKeao YangKeao requested a review from Defined2014 November 20, 2024 07:44
@ti-chi-bot ti-chi-bot bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Nov 20, 2024
Copy link
Contributor

@dveeden dveeden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CREATE TABLE t1(id INT PRIMARY KEY, d1 DATE, d2 DATETIME, t1 TIME, t2 TIMESTAMP, b1 BIT, b2 BINARY);
INSERT INTO t1 VALUES (1, '2024-06-14', '2024-06-14 09:37:00', '09:37:00', '2024-06-14 09:37:00', b'0', 0x41);
SELECT JSON_TYPE(b2) FROM t1;

TiDB:

mysql-8.0.11-TiDB-v8.5.0-alpha-160-gce19496ae9-dirty> SELECT JSON_TYPE(b2) FROM t1;
ERROR 3144 (HY000): Cannot create a JSON value from a string with CHARACTER SET 'binary'.

MySQL 9.1.0:

mysql-9.1.0> SELECT JSON_TYPE(b2) FROM t1;
ERROR 3144 (22032): Cannot create a JSON value from a string with CHARACTER SET 'binary'.

The SQL State is 22032 for MySQL and HY000 for TiDB

@ti-chi-bot ti-chi-bot bot removed the lgtm label Nov 20, 2024
@dveeden
Copy link
Contributor

dveeden commented Nov 20, 2024

diff --git a/pkg/parser/mysql/errcode.go b/pkg/parser/mysql/errcode.go
index 05d5dc3e69..bfbd196138 100644
--- a/pkg/parser/mysql/errcode.go
+++ b/pkg/parser/mysql/errcode.go
@@ -898,6 +898,7 @@ const (
 	ErrInvalidJSONText                                       = 3140
 	ErrInvalidJSONTextInParam                                = 3141
 	ErrInvalidJSONPath                                       = 3143
+	ErrInvalidJSONCharset                                    = 3144
 	ErrInvalidTypeForJSON                                    = 3146
 	ErrInvalidJSONPathWildcard                               = 3149
 	ErrInvalidJSONContainsPathType                           = 3150
diff --git a/pkg/parser/mysql/errname.go b/pkg/parser/mysql/errname.go
index f757f825da..845c50a21b 100644
--- a/pkg/parser/mysql/errname.go
+++ b/pkg/parser/mysql/errname.go
@@ -907,6 +907,7 @@ var MySQLErrName = map[uint16]*ErrMessage{
 	ErrInvalidJSONText:                                       Message("Invalid JSON text: %-.192s", nil),
 	ErrInvalidJSONTextInParam:                                Message("Invalid JSON text in argument %d to function %s: \"%s\" at position %d.", nil),
 	ErrInvalidJSONPath:                                       Message("Invalid JSON path expression %s.", nil),
+	ErrInvalidJSONCharset:                                    Message("Cannot create a JSON value from a string with CHARACTER SET '%s'.", nil),
 	ErrInvalidTypeForJSON:                                    Message("Invalid data type for JSON data in argument %d to function %s; a JSON string or JSON type is required.", nil),
 	ErrInvalidJSONPathWildcard:                               Message("In this situation, path expressions may not contain the * and ** tokens or an array range.", nil),
 	ErrInvalidJSONContainsPathType:                           Message("The second argument can only be either 'one' or 'all'.", nil),
diff --git a/pkg/parser/mysql/state.go b/pkg/parser/mysql/state.go
index 2cbc6f1d2b..307965d088 100644
--- a/pkg/parser/mysql/state.go
+++ b/pkg/parser/mysql/state.go
@@ -254,6 +254,7 @@ var MySQLState = map[uint16]string{
 	ErrInvalidJSONText:                     "22032",
 	ErrInvalidJSONTextInParam:              "22032",
 	ErrInvalidJSONPath:                     "42000",
+	ErrInvalidJSONCharset:                  "22032",
 	ErrInvalidJSONData:                     "22032",
 	ErrInvalidJSONPathWildcard:             "42000",
 	ErrJSONUsedAsKey:                       "42000",

@YangKeao
Copy link
Member Author

CREATE TABLE t1(id INT PRIMARY KEY, d1 DATE, d2 DATETIME, t1 TIME, t2 TIMESTAMP, b1 BIT, b2 BINARY);
INSERT INTO t1 VALUES (1, '2024-06-14', '2024-06-14 09:37:00', '09:37:00', '2024-06-14 09:37:00', b'0', 0x41);
SELECT JSON_TYPE(b2) FROM t1;

TiDB:

mysql-8.0.11-TiDB-v8.5.0-alpha-160-gce19496ae9-dirty> SELECT JSON_TYPE(b2) FROM t1;
ERROR 3144 (HY000): Cannot create a JSON value from a string with CHARACTER SET 'binary'.

MySQL 9.1.0:

mysql-9.1.0> SELECT JSON_TYPE(b2) FROM t1;
ERROR 3144 (22032): Cannot create a JSON value from a string with CHARACTER SET 'binary'.

The SQL State is 22032 for MySQL and HY000 for TiDB

Nice catch! Fixed. PTAL @dveeden

@YangKeao YangKeao requested a review from dveeden November 20, 2024 08:06
@ti-chi-bot ti-chi-bot bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Nov 20, 2024
@YangKeao
Copy link
Member Author

/cc @tangenta

@ti-chi-bot ti-chi-bot bot requested a review from tangenta November 20, 2024 08:16
Copy link

ti-chi-bot bot commented Nov 20, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Defined2014, dveeden, tangenta, windtalker

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot bot added approved lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Nov 20, 2024
Copy link

ti-chi-bot bot commented Nov 20, 2024

[LGTM Timeline notifier]

Timeline:

  • 2024-11-20 07:20:58.230885252 +0000 UTC m=+16245.850539762: ☑️ agreed by windtalker.
  • 2024-11-20 07:46:21.476029771 +0000 UTC m=+17769.095684286: ☑️ agreed by Defined2014.
  • 2024-11-20 07:49:09.712439329 +0000 UTC m=+17937.332093840: ✖️🔁 reset by dveeden.
  • 2024-11-20 08:10:34.934725757 +0000 UTC m=+19222.554380274: ☑️ agreed by dveeden.
  • 2024-11-20 08:20:27.542743478 +0000 UTC m=+19815.162397993: ☑️ agreed by tangenta.

@YangKeao
Copy link
Member Author

/retest

1 similar comment
@YangKeao
Copy link
Member Author

/retest

@ti-chi-bot ti-chi-bot bot merged commit db4d19b into pingcap:master Nov 20, 2024
24 checks passed
@ti-chi-bot
Copy link
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #57567.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error 3144 (HY000): Cannot create a JSON value from a string with CHARACTER SET 'binary'. Using JSON_TYPE on non-JSON values should return an error
6 participants